"use strict";
const cfg = require("../config/server");
const fs = require("fs");
const getBasicResponseData = function(code) {
	return {
		status: code,
		msg: require("./status_code")[code] || "unknow ecode"
	};
};
const assemblyResponseData = function(code, additionalData) {
	const responseData = getBasicResponseData(code);
	responseData.results = additionalData;
	return responseData;
};
const getResponseFunc = function(res) {
	const success = function(data) {
		const returnedData = assemblyResponseData("ok", data);
		res.json(returnedData);
		return data;
	};
	const fail = function(e) {
		let error = e;
		if (!(error instanceof Error)) {
			console.error("需要更新遗留代码的错误抛出方式啦", e);
			error = new Error("88888");
		}
		const returnedData = assemblyResponseData(error.message, error.additionalData);
		res.json(returnedData);
		console.error(e, e.stack);
		return e;
	};
	return {
		success: success,
		fail: fail
	};
};
const assemblyCtx = function(domainId, orgId) {
	const cfg = require("../env");
	cfg.domainId = domainId;
	cfg.orgId = orgId;
	return cfg;
};

const getErrorFunc = function(res, responseFunc) {
	return function(e) {
		console.error("服务器错误", e, e.stack);
		const client = responseFunc || getResponseFunc(res);
		client.fail(e);
	};
};

const getCurrentAccountId = function(req) {
	const currentAccount = req.session.accounts.find(account => account._id == req.session.currentAccountId);
	return currentAccount._id;
};
const getFileExtension = function(fileName) {
	const reg = /[^.]+$/;
	const result = fileName.match(reg);
	if (result === null) {
		return null;
	} else {
		return result[0];
	}
};
const removeSlash = function(url) {
	return url.replace(new RegExp("/+$"), "");
};


const mediaIdToUrl = function(obj) {
	if (!obj) {
		return;
	}
	Object.keys(obj).forEach(key => {
		try {
			const element = obj[key];
			if (Array.isArray(element)) {
				obj[key].forEach(mediaIdToUrl);
			} else if (typeof element === "object") {
				mediaIdToUrl(element);
			} else if (element && (key === "mediaId" || key === "avatar" || key === "homePageBackground")) {
				obj[key] = `${cfg.apiServer.public}/medias/images/${element}`;
			}
		} catch (e) {
			console.error(key, obj, e);
		}
	});
	return obj;
};
const arrayToHashObj = function(array, keyName, valueName) {
	const hashObj = {};
	array.forEach(item => {
		const key = keyName ? item[keyName] : item;
		const value = valueName ? item[valueName] : item;
		hashObj[key] = value;
	});
	return hashObj;
};
const getDomainAndOrgFrom = function(param, info) {
	param.domainId = info.domainId;
	param.orgId = info.orgId;
};
const hasDomainAndOrg = obj => obj.domainId && obj.orgId;
const getAtworkInstance = function(req) {
	const config = require("../config/server");
	const atwork = require("atwork");
	const param = {
		clientId: config.clientId,
		clientSecret: config.clientSecret,
		adminServer: config.apiServer.internal,
	};
	if (req.session.account) { //如果是已经登陆了，则从session中获取信息
		getDomainAndOrgFrom(param, req.session.account);
	} else if (hasDomainAndOrg(req.body)) { //否则试图从body中获取
		getDomainAndOrgFrom(param, req.body);
	} else if (hasDomainAndOrg(req.query)) { //或者从query中获取
		getDomainAndOrgFrom(param, req.query);
	} else {
		console.error("不能获取域和组织");
		throw new Error("e_params");
	}
	const instance = atwork(param);
	return instance;
};

const writeDatasToFile = function(iterator, file) {
	let writable;
	try {
		writable = fs.createWriteStream(file);
	} catch (e) {
		return Promise.reject(e);
	}
	return new Promise((success) => {
		(function write() {
			let cursor = iterator.next();
			while (!cursor.done) {
				if (writable.write(cursor.value)) {
					///console.log("写入数据ok", cursor.value)
					cursor = iterator.next();
				} else {
					writable.on("drain", writable);
					//console.log("写入数据缓存",cursor.value)
					return;
				}
			}
			writable.end();
			writable.on("finish", success);
		})();
	});
};

module.exports = {
	getResponseFunc,
	assemblyCtx,
	getErrorFunc,
	getCurrentAccountId,
	getFileExtension,
	removeSlash,
	mediaIdToUrl,
	arrayToHashObj,
	getAtworkInstance,
	writeDatasToFile
};